#include "BondDetailCache.h"
#include <core/time/time.h>

#define MAX_CACHE_COUNT 20

BondDetailCache& BondDetailCache::instance()
{
	static BondDetailCache bdc;
	return bdc;
}

BondDetailCache::BondDetailCache()
{
}

BondDetailCache::~BondDetailCache()
{
	for (auto it = m_mapData.begin(); it != m_mapData.end(); ++it)
	{
		delChart(it->second);
	}

	m_mapData.clear();
}

BondDetailChartData& BondDetailCache::getChart(const std::string& strBondKey)
{
	auto it = m_mapData.find(strBondKey);
	if (it == m_mapData.end())
	{
		if (m_mapData.size() > MAX_CACHE_COUNT)
		{
			eliminateCache();
		}

		BondDetailChartData* chart = new BondDetailChartData();
		m_mapData.insert(std::make_pair(strBondKey, chart));
		mTicks.push_back(chart->tickTime());
		return *chart;
	}

	it->second->updateTick();
	return *it->second;
}

bool BondDetailCache::hasCache(const std::string& strBondKey)
{
	auto it = m_mapData.find(strBondKey);
	if (it == m_mapData.end())
	{
		return false;
	}

	return true;
}

void BondDetailCache::eliminateCache()
{
	std::sort(mTicks.begin(), mTicks.end());

	int idx = MAX_CACHE_COUNT / 2;
	if (idx >= (int)mTicks.size()) return;
	uint32_t cacheTick = mTicks[idx];

	auto it = m_mapData.begin();
	for (;it != m_mapData.end();)
	{
		if ((it->second->tickTime()) <= cacheTick)
		{
			delChart(it->second);
			m_mapData.erase(it++);
		}
		else
		{
			it++;
		}
	}

	mTicks.erase(mTicks.begin(), mTicks.begin() + idx);
}

void BondDetailCache::delChart(BondDetailChartData* chart)
{
	if (chart)
	{
		if (chart->m_pAaprismtHisData)
		{
			delete chart->m_pAaprismtHisData;
		}
		if (chart->m_pDealCurveKLineEx)
		{
			delete chart->m_pDealCurveKLineEx;
		}
		if (chart->m_pDealCurveKLineBroker)
		{
			delete chart->m_pDealCurveKLineBroker;
		}
		if (chart->m_pDealCurveKLineCFETS)
		{
			delete chart->m_pDealCurveKLineCFETS;
		}

		if (chart->m_pInterestBond)
		{
			delete chart->m_pInterestBond;
		}
		if (chart->m_pInterestIssuer)
		{
			delete chart->m_pInterestIssuer;
		}
		if (chart->m_pBrokerDealKlineBrokerDayClose)
		{
			delete chart->m_pBrokerDealKlineBrokerDayClose;
		}
		if (chart->m_pDealKlineDayCloseEx)
		{
			delete chart->m_pDealKlineDayCloseEx;
		}
		if (chart->m_pCfetsDealKlineCfetsDayClose)
		{
			delete chart->m_pCfetsDealKlineCfetsDayClose;
		}
		if (chart->m_pKlintDayCloseBoList)
		{
			delete chart->m_pKlintDayCloseBoList;
		}
		if (chart->m_pYieldCurve)
		{
			delete chart->m_pYieldCurve;
		}

		delete chart;
	}
}

BondDetailChartData::BondDetailChartData()
{
	mTick = qb::base::GetHighResTime();
}

void BondDetailChartData::updateTick()
{
	mTick = qb::base::GetHighResTime();
}
